Redisson 六种锁详解
1. RLock — 可重入锁
最基础的分布式锁,同一线程可以多次加锁而不会死锁,内部用计数器记录重入次数。
java
RLock lock = redissonClient.getLock("myLock");
lock.lock(); // 计数器: 1
lock.lock(); // 计数器: 2(同一线程,不阻塞)
lock.unlock(); // 计数器: 1
lock.unlock(); // 计数器: 0,真正释放底层 Redis 结构: Hash
key = "myLock"
field = "线程唯一标识"
value = 重入次数2. RFairLock — 公平锁
在 RLock 基础上保证按请求顺序依次获得锁,内部维护一个等待队列,先到先得,避免线程饥饿。
java
RLock fairLock = redissonClient.getFairLock("myFairLock");
fairLock.lock();
try {
// 保证等待最久的线程优先获锁
} finally {
fairLock.unlock();
}⚠️ 代价是性能比 RLock 低,非必要不用。适合对顺序公平性有严格要求的场景(如资源调度)。
3. RReadWriteLock — 读写锁
经典的读写分离锁:读读不互斥,读写、写写互斥,适合读多写少的场景。
java
RReadWriteLock rwLock = redissonClient.getReadWriteLock("myRWLock");
// 读操作(多线程可并发)
RLock readLock = rwLock.readLock();
readLock.lock();
try {
// 查询数据
} finally {
readLock.unlock();
}
// 写操作(独占)
RLock writeLock = rwLock.writeLock();
writeLock.lock();
try {
// 更新数据
} finally {
writeLock.unlock();
}| 并发情况 | 是否互斥 |
|---|---|
| 读 + 读 | ✅ 不互斥,并发执行 |
| 读 + 写 | ❌ 互斥,阻塞等待 |
| 写 + 写 | ❌ 互斥,阻塞等待 |
4. RMultiLock — 联锁
将多个 RLock 绑定为一个整体,必须所有锁全部加锁成功才算成功,全部一起释放。
java
RLock lock1 = redissonClient.getLock("lock:order");
RLock lock2 = redissonClient.getLock("lock:inventory");
RLock lock3 = redissonClient.getLock("lock:account");
RLock multiLock = redissonClient.getMultiLock(lock1, lock2, lock3);
multiLock.lock(); // 三个锁全部加锁成功才继续
try {
// 需要同时操作多个资源的业务
} finally {
multiLock.unlock(); // 一次性全部释放
}💡 典型场景:下单时需要同时锁住订单、库存、账户,防止任意两个资源间的并发冲突。
5. RSemaphore — 信号量
控制同时访问某资源的线程数量上限,本质是一个计数器,适合限流、连接池控制等场景。
java
RSemaphore semaphore = redissonClient.getSemaphore("mySemaphore");
semaphore.trySetPermits(5); // 最多允许 5 个线程同时访问
semaphore.acquire(); // 占用 1 个许可(没有则阻塞)
try {
// 访问受限资源(如数据库连接)
} finally {
semaphore.release(); // 归还许可
}💡 典型场景:停车场限流(只有 100 个车位)、数据库连接数控制、API 并发数限制。
6. RCountDownLatch — 倒计时锁
让一个或多个线程等待,直到其他线程都完成任务后再继续执行,是协调多线程的同步工具。
java
RCountDownLatch latch = redissonClient.getCountDownLatch("myLatch");
latch.trySetCount(3); // 需要等待 3 个任务完成
// --- 等待方(主线程)---
latch.await(); // 阻塞,直到计数归零
System.out.println("所有子任务完成,开始汇总");
// --- 执行方(3 个工作线程)---
// 每个任务完成后调用:
latch.countDown(); // 计数 -1,减到 0 时唤醒等待方💡 典型场景:分布式并行任务聚合(如多个服务并行查询,全部返回后合并结果)。
横向对比总结
| 锁类型 | 核心能力 | 典型场景 |
|---|---|---|
RLock | 可重入,单资源互斥 | 通用分布式锁 |
RFairLock | 公平排队,防饥饿 | 资源调度、顺序敏感 |
RReadWriteLock | 读并发,写互斥 | 缓存读多写少 |
RMultiLock | 多资源原子加锁 | 跨资源事务操作 |
RSemaphore | 限制并发数量 | 限流、连接池 |
RCountDownLatch | 多任务完成同步 | 分布式并行聚合 |
选锁原则: 单资源保护用
RLock;读多写少用读写锁;跨多资源用联锁;限制并发数用信号量;等待多任务完成用倒计时锁。